package com.education.platform.api.service.impl;

import com.education.platform.api.config.ThreadUser;
import com.education.platform.api.service.AccountService;
import com.education.platform.api.service.PointsFlowService;
import com.education.platform.api.service.common.CacheDataService;
import com.education.platform.api.vo.request.ChallengeResultVO;
import com.education.platform.api.vo.request.UserPointsUpdateVO;
import com.education.platform.api.vo.response.PointsRankVO;
import com.education.platform.common.enums.FlowTypeEnum;
import com.education.platform.common.enums.PointsTypeEnum;
import com.education.platform.common.exception.AssertException;
import com.education.platform.common.exception.BusinessException;
import com.education.platform.common.redis.RedisUtils;
import com.education.platform.dao.StudyRecordDao;
import com.education.platform.dao.entity.ExaminPaperDO;
import com.education.platform.dao.entity.PointsFlowDO;
import com.education.platform.dao.entity.StudyRecordDO;
import com.education.platform.dao.entity.UserPointsDO;
import com.education.platform.dao.model.PointsRankModel;

import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.factory.annotation.Autowired;
import com.education.platform.common.service.impl.BaseServiceImpl;
import com.education.platform.dao.UserPointsDao;
import org.springframework.stereotype.Service;
import com.education.platform.api.service.UserPointsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
* describe: 积分表
* @author : tomato
* @date: 2020-06-06 03:07:32.843
**/
@Service
public class UserPointsServiceImpl extends BaseServiceImpl<UserPointsDao, UserPointsDO> implements UserPointsService {

	private static final Logger LOGGER = LoggerFactory.getLogger(UserPointsServiceImpl.class);

    @Autowired
	private UserPointsDao userPointsDao;
    @Autowired
    private PointsFlowService pointsFlowService;

    @Autowired
    private CacheDataService cacheDataService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private StudyRecordDao studyRecordDao;
    @Autowired
    private AccountService accountService;

    /**
     * 挑战答题
     * 同时保存到redis
     * @param point
     * @param businessType
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChallengeResultVO challenge(Float point,Integer numbers ,Integer businessType) {
            //保存挑战所得积分
        float realPoint =  cacheDataService.userPointsOperate(point,businessType);
        //保存挑战 答对的数量
        ChallengeResultVO resultVO = cacheDataService.userChallenge(numbers);
        boolean vip = accountService.isVip(ThreadUser.getUserId());
        if(realPoint >0 && vip){
            Integer userId = ThreadUser.getUserId();
            UserPointsDO query = new UserPointsDO();
            query.setDeleted(false);
            query.setStatus(true);
            query.setUserId(userId);
            UserPointsDO userPointsDO  = userPointsDao.get(query);
            if(userPointsDO == null){
                AssertException.throwBusinessEp("积分账户异常！");
            }
           //积分表增加记录
           userPointsDao.addPoints(realPoint,userId);
           //增加积分流水

           PointsFlowDO pointsFlowDO = new PointsFlowDO();
           pointsFlowDO.setBeforeNumber(userPointsDO.getPoints()==null?0f:userPointsDO.getPoints());
           pointsFlowDO.setFlowType(FlowTypeEnum.IN.getValue());
           pointsFlowDO.setCreateTime(new Date());
           pointsFlowDO.setFlowNumber(realPoint);
           pointsFlowDO.setAfterNumber(realPoint+pointsFlowDO.getBeforeNumber());
           pointsFlowDO.setDeleted(false);
           pointsFlowDO.setBusinessType(businessType);
           pointsFlowDO.setUserId(userId);
           pointsFlowService.insert(pointsFlowDO);
       }
        return resultVO;
    }

    /**
     * 增加积分
     * 同时保存到redis
     * @param
     * @param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addPoints( UserPointsUpdateVO userPointsUpdateVO) {
        Float point = userPointsUpdateVO.getPoints();
        int businessType = userPointsUpdateVO.getBusinessType();
        float realPoint ;
        if(PointsTypeEnum.LEARN_VIDEO.getValue().equals(businessType)||
                PointsTypeEnum.LEARN_ARTICLE.getValue().equals(businessType)){

            if(userPointsUpdateVO.getTopicId() == null){
                throw new BusinessException("topicId不能为空");
            }
            StudyRecordDO recordQuery = new StudyRecordDO();
            recordQuery.setTopicId(userPointsUpdateVO.getTopicId());
            recordQuery.setType(businessType);
            recordQuery.setUserId(ThreadUser.getUserId());
            StudyRecordDO record = studyRecordDao.get(recordQuery);

            if(record != null){
                //视频或者文章已经浏览过，不再算积分
                return;
            }else{
                recordQuery.setCreateTime(new Date());
                studyRecordDao.insert(recordQuery);
            }

        }
        realPoint =cacheDataService.userPointsOperate(point,businessType);
        if(realPoint>0){
            Integer userId = ThreadUser.getUserId();
            //增加积分流水
            UserPointsDO query = new UserPointsDO();
            query.setDeleted(false);
            query.setStatus(true);
            query.setUserId(userId);
            UserPointsDO userPointsDO  = userPointsDao.get(query);
            if(userPointsDO == null){
                AssertException.throwBusinessEp("积分账户异常！");
            }
            //增加积分
            userPointsDao.addPoints(realPoint,userId);

            PointsFlowDO pointsFlowDO = new PointsFlowDO();
            pointsFlowDO.setBeforeNumber(userPointsDO.getPoints()==null?0f:userPointsDO.getPoints());
            pointsFlowDO.setFlowType(FlowTypeEnum.IN.getValue());
            pointsFlowDO.setCreateTime(new Date());
            pointsFlowDO.setFlowNumber(realPoint);
            pointsFlowDO.setAfterNumber(realPoint+pointsFlowDO.getBeforeNumber());
            pointsFlowDO.setDeleted(false);
            pointsFlowDO.setUserId(userId);
            pointsFlowDO.setBusinessType(businessType);
            pointsFlowService.insert(pointsFlowDO);
        }
    }


    /**
     * 获取积分排序列表
     *
     * @return
     */
    @Override
    public List<PointsRankModel> getRankList() {
        return userPointsDao.getRankList();
    }

    /**
     * 获取用户积分排名
     * @param userId
     * @return
     */
    @Override
     public PointsRankModel getRankByUserId(Integer userId){
        return userPointsDao.getRankByUserId(userId);
    }
}
